/**
 * Copyright (C) 2016 Hyphenate Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyphenate.tfj;

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Process;
import android.util.Log;

import androidx.multidex.MultiDex;

import com.easemob.qiniu_sdk.PushStreamHelper;
import com.hyphenate.EMConnectionListener;
import com.hyphenate.EMError;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.easeui.EaseUI;
import com.hyphenate.push.EMPushHelper;
import com.hyphenate.push.EMPushType;
import com.hyphenate.push.PushListener;
import com.hyphenate.tfj.live.common.UserActivityLifecycleCallbacks;
import com.hyphenate.tfj.ui.MainActivity;
import com.hyphenate.util.EMLog;
import com.tfj.comm.bean.DemoCache;

import java.util.Iterator;
import java.util.List;

public class DemoApplication extends Application implements Thread.UncaughtExceptionHandler{

	public static Context applicationContext;
	private static DemoApplication instance;
	// login user name
	public final String PREF_USERNAME = "username";
    private final static String TAG = "DemoApplication";
	/**
	 * nickname for current user, the nickname instead of ID be shown when user receive notification from APNs
	 */
	public static String currentUserNick = "";

	@Override
	public void onCreate() {
		MultiDex.install(this);
		super.onCreate();
        applicationContext = this;
        instance = this;
		DemoCache.setContext(this);
		//init demo helper
        DemoHelperChat.getInstance().init(applicationContext);

        // 请确保环信SDK相关方法运行在主进程，子进程不会初始化环信SDK（该逻辑在EaseUI.java中）
		if (EaseUI.getInstance().isMainProcess(this)) {
			// 初始化华为 HMS 推送服务, 需要在SDK初始化后执行
			//HMSPushHelper.getInstance().initHMSAgent(instance);

			EMPushHelper.getInstance().setPushListener(new PushListener() {
				@Override
				public void onError(EMPushType pushType, long errorCode) {
					// TODO: 返回的errorCode仅9xx为环信内部错误，可从EMError中查询，其他错误请根据pushType去相应第三方推送网站查询。
					EMLog.e("PushClient", "Push client occur a error: " + pushType + " - " + errorCode);
				}
            });
		}
		//直播相关
		registerActivityLifecycleCallbacks();
		registerUncaughtExceptionHandler();
		PushStreamHelper.getInstance().init(this);
		initChatSdk();
	}

	public static DemoApplication getInstance() {
		return instance;
	}
	@Override
	protected void attachBaseContext(Context base) {
		super.attachBaseContext(base);
		MultiDex.install(this);
	}
	//直播相关
	private void registerActivityLifecycleCallbacks() {
		this.registerActivityLifecycleCallbacks(mLifecycleCallbacks);
	}
	private UserActivityLifecycleCallbacks mLifecycleCallbacks = new UserActivityLifecycleCallbacks();
	public UserActivityLifecycleCallbacks getActivityLifecycle() {
		return mLifecycleCallbacks;
	}
	private void registerUncaughtExceptionHandler() {
		Thread.setDefaultUncaughtExceptionHandler(this);
	}
	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.exit(1);
		Process.killProcess(Process.myPid());
	}

	private void initChatSdk(){
		EMOptions options = new EMOptions();
//    options.enableDNSConfig(true);
//    options.setRestServer("a1-hsb.easemob.com");
//    options.setIMServer("116.85.43.118");
//    options.setImPort(6717);

		EmClientInit(this, options);

		EMClient.getInstance().setDebugMode(BuildConfig.DEBUG);

		EMClient.getInstance().addConnectionListener(new EMConnectionListener() {
			@Override public void onConnected() {

			}

			@Override public void onDisconnected(int errorCode) {
				if(errorCode == EMError.USER_LOGIN_ANOTHER_DEVICE)
				{
					Intent intent = new Intent(getApplicationContext(), MainActivity.class);
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					intent.putExtra("conflict", true);
					startActivity(intent);
				}
			}
		});
	}

	private void EmClientInit(DemoApplication context, EMOptions options) {
		int pid = android.os.Process.myPid();
		String processAppName = getAppName(context, pid);

		Log.d("", "process app name : " + processAppName);

		// if there is application has remote service, application:onCreate() maybe called twice
		// this check is to make sure SDK will initialized only once
		// return if process name is not application's name since the package name is the default process name
		if (processAppName == null || !processAppName.equalsIgnoreCase(context.getPackageName())) {
			Log.e(TAG, "enter the service process!");
			return;
		}
		if(options == null){
			EMClient.getInstance().init(context, initChatOptions());
		}else{
			EMClient.getInstance().init(context, options);
		}

	}

	private EMOptions initChatOptions() {
		Log.d(TAG, "init HuanXin Options");

		EMOptions options = new EMOptions();
		// change to need confirm contact invitation
		options.setAcceptInvitationAlways(false);
		// set if need read ack
		options.setRequireAck(true);
		// set if need delivery ack
		options.setRequireDeliveryAck(false);

		return options;
	}
	/**
	 * check the application process name if process name is not qualified, then we think it is a service process and we will not init SDK
	 * @param pID
	 * @return
	 */
	private String getAppName(Context context, int pID) {
		String processName = null;
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		List l = am.getRunningAppProcesses();
		Iterator i = l.iterator();
		PackageManager pm = context.getPackageManager();
		while (i.hasNext()) {
			ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
			try {
				if (info.pid == pID) {
					CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
					// Log.d("Process", "Id: "+ info.pid +" ProcessName: "+
					// info.processName +"  Label: "+c.toString());
					// processName = c.toString();
					processName = info.processName;
					return processName;
				}
			} catch (Exception e) {
				// Log.d("Process", "Error>> :"+ e.toString());
			}
		}
		return processName;
	}
}
